package com.okq.util;

import com.google.gson.Gson;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.lang.reflect.Type;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.Properties;

/**
 * 描述 : 基本工具类
 * 作者 : zdl
 * 日期 : 2017/3/15 13:28
 */
public class BaseTool {

    private static int _suffix = 0;// 随机后缀

    /**
     * 日志
     */
    private static final Logger logger = Logger.getLogger(BaseTool.class);

    /**
     * 读取properties配置文件中的value值
     *
     * @param srcFile properties配置文件的路径
     * @param key     properties配置文件中的key
     * @return properties配置文件中的value
     */
    @SuppressWarnings("all")
    public static String getPropertiesValue(String srcFile, String key) {
        String result = "";
        InputStream is = null;
        try {
            Properties properties = new Properties();
            URL url = Thread.currentThread().getContextClassLoader().getResource(srcFile);
            if (url != null) {
                String path = url.getPath();
                path = URLDecoder.decode(path, "utf-8");
                is = new FileInputStream(path);
                properties.load(is);
                result = (String) properties.get(key);
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (is != null)
                    is.close();
            } catch (IOException ioe) {
                logger.error(ioe.getMessage(), ioe);
            }
        }
        return result;
    }

    /**
     * 生成自定义字符串（表主键用）
     *
     * @return 主键
     */
    public static synchronized String getPK() {
        _suffix = 0;
        String strTmp = TimeTool.formatDate(new Date(), "yyMMddHHmmssSSS");
        _suffix++;
        if (_suffix > 999) {
            _suffix = 0;
        }
        strTmp = strTmp + String.format("%03d", _suffix);
        return strTmp;
    }

    /**
     * 根据格式获取参数字符串
     *
     * @param format 特定格式
     * @return String
     */
    public static synchronized String getNumByFormat(String format) {
        _suffix = 0;
        String strTmp = TimeTool.formatDate(new Date(), format);
        _suffix++;
        if (_suffix > 999) {
            _suffix = 0;
        }
        strTmp = strTmp + String.format("%03d", _suffix);
        return strTmp;
    }

    /**
     * 生成设备编号
     *
     * @return 设备编号
     */
    public static synchronized String getEqCode() {
        _suffix = 0;
        String strTmp = TimeTool.formatDate(new Date(), "yyyyMMdd");
        _suffix++;
        if (_suffix > 999) {
            _suffix = 0;
        }
        String eqcode = getPropertiesValue("config.properties", "eqcode");
        if (StringUtils.isBlank(eqcode)) {
            eqcode = "okq";
        }
        strTmp = eqcode + strTmp + String.format("%03d", _suffix);
        return strTmp;
    }

    /**
     * 生产企业代码
     *
     * @return 企业代码
     */
    public static synchronized String getNum() {
        _suffix = 0;
        String str = "40101";
        _suffix++;
        if (_suffix > 999) {
            _suffix = 0;
        }
        str = str + String.format("%03d", _suffix);
        return str;
    }

    /**
     * 返回指定格式字符串
     *
     * @param format 格式
     * @param num    数字
     * @return 指定格式的数字
     */
    public static String zeroFormat(String format, int num) {
        DecimalFormat df = new DecimalFormat(format);
        return df.format(num);
    }

    /**
     * double类型的数据转为特定类型的String
     *
     * @param d1      double数
     * @param pattern 类型
     * @return String
     */
    public static String getStrByDouble(double d1, String pattern) {
        DecimalFormat df = new DecimalFormat(pattern);
        return df.format(d1);
    }

    /**
     * 对象转换成json字符串
     *
     * @param obj 对象
     * @return json字符串
     */
    public static String toJson(Object obj) {
        Gson gson = new Gson();
        return gson.toJson(obj);
    }

    /**
     * json字符串转成对象
     *
     * @param str  Json字符串
     * @param type 类型
     * @return 对象
     */
    public static <T> T fromJson(String str, Type type) {
        Gson gson = new Gson();
        return gson.fromJson(str, type);
    }

    /**
     * 对字节数组字符串进行Base64解码并生成图片
     *
     * @param imgStr      图片数据
     * @param imgFilePath 保存图片全路径地址
     * @return 是否成功
     */
    @SuppressWarnings("all")
    public static boolean generateImage(String imgStr, String imgFilePath) {
        boolean isSuccess = false;
        OutputStream out = null;
        if (imgStr == null) // 图像数据为空
            isSuccess = false;
        try {
            // Base64解码
            byte[] b = Base64.decodeBase64(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 调整异常数据
                    b[i] += 256;
                }
            }
            // 生成图片
            out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            isSuccess = true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            try {
                if (out != null)
                    out.close();
            } catch (IOException ex) {
                logger.error(ex.getMessage(), ex);
            }
        }
        return isSuccess;
    }

    /**
     * 判断路径是否存在,不存在则创建
     *
     * @param path 文件路径
     * @return 是否创建成功
     */
    public static boolean fileExists(String path) {
        File file = new File(path);
        // 如果文件夹不存在则创建
        boolean isCreated = false;
        if (!file.exists() && !file.isDirectory()) {
            isCreated = file.mkdirs();
        } else if (file.exists() && file.isDirectory()) {
            isCreated = true;
        }
        return isCreated;
    }

    /**
     * 删除文件
     *
     * @param path 文件路径
     */
    public static void delteFile(String path) {
        try {
            if (StringUtils.isNotBlank(path)) {
                File file = new File(path);
                if (file.exists()) {
                    file.delete();
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * MD5加密
     *
     * @param str 字符串
     * @return MD5加密后的字符串
     */
    public static String getMD5Encryption(String str) {
        String strMD5 = "";
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes(Charset.forName("UTF-8")));
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            strMD5 = new BigInteger(1, md.digest()).toString(16).toLowerCase();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return strMD5;
    }

    /**
     * 获取请求服务器路径
     *
     * @param request 请求
     * @return basePath
     */
    public static String getServerPath(HttpServletRequest request) {
        String basePath = "";
        try {
            String path = request.getContextPath();
            if (StringUtils.isNotBlank(path)) {
                path = File.separator + path.substring(1, path.length());
            }
            basePath = request.getScheme() + ":" + File.separator + File.separator + request.getServerName() + ":" + request.getServerPort() + path + File.separator;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return basePath;
    }

    /**
     * 普通classes获取web项目根路径
     *
     * @return web项目跟路径
     */
    public static String getWebRootPathByClasses() {
        String path = "";
        try {
            URL url = BaseTool.class.getClassLoader().getResource(File.separator);
            if (url != null) {
                String webPath = url.getPath();
                String itemName = getPropertiesValue("config.properties", "itemName");
                if (StringUtils.isNotBlank(itemName)) {
                    path = webPath.substring(1, webPath.indexOf(itemName) + itemName.length());
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return path;
    }

    /**
     * 解决设置名称时的乱码
     *
     * @param request:请求数据
     * @param fileNames:文件名称
     * @return 正确的文件名
     */
    public static String processFileName(HttpServletRequest request, String fileNames) {
        String codedfilename = null;
        try {
            String agent = request.getHeader("USER-AGENT");
            if (null != agent && agent.contains("MSIE") || null != agent && agent.contains("Trident")) {// ie
                codedfilename = java.net.URLEncoder.encode(fileNames, "UTF8");
            } else if (null != agent && agent.contains("Edge")) {
                codedfilename = new String(fileNames.getBytes("GBK"), "iso-8859-1");
            } else if (null != agent && agent.contains("Mozilla")) {// 火狐,chrome等
                codedfilename = new String(fileNames.getBytes("UTF-8"), "iso-8859-1");
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return codedfilename;
    }

    public static void main(String[] args) {
        System.out.println(getPK());
    }

}
